﻿using ManageSystem.Model;
using ManageSystem.IService;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ManageSystem.IRepository;
using ManageSystem.Repository;

namespace ManageSystem.Service
{
    public class OutlayStreamService : BaseService<OutlayStream>, IOutlayStreamService
    {
        public IOutlayStreamRepository outlayStreamDal = new OutlayStreamRepository();

        public async Task<List<OutlayStream>> QueryOutlayStreamByProjectGuid(string projectGuid)
        {
            return await outlayStreamDal.QueryOutlayByProjectGuid(projectGuid);
        }

        // 添加或者更新支出流水时，对项目的已到账、未到账金额和支出合计
        public async Task<Project> DealWithOutlayStreamsOfProject(OutlayStream outlayStream, Project projectToBeUpdated, string mode)
        {
            // 当前支出金额和更新前的支出金额的差值.
            // 如果是删除，变成totalPay的负数
            decimal outlayBias = mode == "delete" ? outlayStream.totalPay * -1 : outlayStream.totalPay - outlayStream.oldTotalPay;

            // 更新项目支出合计
            projectToBeUpdated.outlayAmount += outlayBias;

            // 更新项目的预算和支出
            // DELEGATE
            // Traverse the properties
            foreach (System.Reflection.PropertyInfo p in outlayStream.GetType().GetProperties())
            {
                if (p.Name.Contains("pay") && p.Name.Length == 4)
                {
                    string keyOfProject = p.Name + "out";
                    // get the key-value pair of 支出
                    var propertyOfProject = projectToBeUpdated.GetType().GetProperty(keyOfProject);
                    // 待更新的支出
                    decimal oldValue = Convert.ToDecimal(propertyOfProject.GetValue(projectToBeUpdated));
                    // 该收入流水中的支出（增删改都可能）
                    decimal valueOfOutlayStream = Convert.ToDecimal(p.GetValue(outlayStream));

                    // 计算预算的变化量
                    switch (mode)
                    {
                        case "delete":
                            valueOfOutlayStream *= -1;
                            break;
                        case "update":
                            OutlayStream outlayStream1 = await outlayStreamDal.QueryByPrimaryKey(outlayStream.streamID);
                            if (outlayStream1 != null)
                            {
                                valueOfOutlayStream -= Convert.ToDecimal(outlayStream1.GetType().GetProperty(p.Name.ToString()).GetValue(outlayStream1));
                            }
                            break;
                    }
                    // 更新支出
                    propertyOfProject.SetValue(projectToBeUpdated, oldValue + valueOfOutlayStream);
                }
            }

            switch (mode)
            {
                // 此时删除支出流水
                case "delete":
                    await outlayStreamDal.DeleteByPrimaryKey(outlayStream.streamID);
                    break;
                // 此时更新支出流水
                case "add":
                    await outlayStreamDal.Add(outlayStream);
                    break;
                case "update":
                    await outlayStreamDal.Update(outlayStream);
                    break;
            }

            // 返回待更新的项目
            return projectToBeUpdated;
        }

        // 删除项目时删除与其相关的支出流水
        public async Task<int> DeleteOutlayStreamByProjectGuid(string projectGuid)
        {
            return await outlayStreamDal.DeleteOutlayStreamByProjectGuid(projectGuid);
        }
    }
}
